package com.cc.utils;

import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.lionsoul.ip2region.xdb.Searcher;

import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.util.Objects;

/**
 * @author shadow
 */
@Slf4j
public class IpUtils {
    public static String getIpAddress(HttpServletRequest request) {
        try {
            String realIp = request.getHeader("X-Real-IP");
            String forwardedIp = request.getHeader("X-Forwarded-For");
            String clientIp = request.getHeader("Proxy-Client-IP");
            String proxyIp = request.getHeader("WL-Proxy-Client-IP");
            String httpClientIp = request.getHeader("HTTP_CLIENT_IP");
            String xForwardedIp = request.getHeader("HTTP_X_FORWARDED_FOR");
            String remoteAddress = InetAddress.getLocalHost().getHostAddress();
            if (StringUtils.isNotEmpty(forwardedIp) && !"unKnown".equalsIgnoreCase(forwardedIp)) {
                //多次反向代理后会有多个Ip值，第一个Ip才是真实Ip
                int index = forwardedIp.indexOf(",");
                if (index != -1) {
                    return forwardedIp.substring(0, index);
                } else {
                    return forwardedIp;
                }
            }
            return StringUtils.isNoneBlank(realIp) && !"unKnown".equalsIgnoreCase(realIp) ? realIp :
                    StringUtils.isNoneBlank(clientIp) && !"unKnown".equalsIgnoreCase(clientIp) ? clientIp :
                            StringUtils.isNoneBlank(proxyIp) && !"unKnown".equalsIgnoreCase(proxyIp) ? proxyIp :
                                    StringUtils.isNoneBlank(httpClientIp) && !"unKnown".equalsIgnoreCase(httpClientIp) ? httpClientIp :
                                            StringUtils.isNoneBlank(xForwardedIp) && !"unKnown".equalsIgnoreCase(xForwardedIp) ? xForwardedIp : remoteAddress;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取用户Ip报错:{}", e.getMessage());
        }
        return "";
    }

    /**
     * 获取类路径下的文件
     *
     * @return
     */
    private static byte[] loadIp2RegionData() {
        try (InputStream inputStream = IpUtils.class.getClassLoader().getResourceAsStream("ip2region.xdb")) {
            if (inputStream == null) {
                throw new RuntimeException("无法找到资源文件 ip2region.xdb");
            }
            return inputStream.readAllBytes();
        } catch (Exception e) {
            throw new RuntimeException("读取资源文件 ip2region.xdb 失败", e);
        }
    }

    /**
     * 将整个库进行缓存到内存，基于这个库创建查询对象来实现基于文件的查询
     * 获取Searcher
     */
    private static Searcher getSearcher() throws IOException {
        //获取地址下的库数据
        byte[] bytes = loadIp2RegionData();
        return Searcher.newWithBuffer(bytes);
    }

    /**
     * 根据ip地址直接返回国家、省、城市信息
     *
     * @param ip ip
     * @return 返回地址
     */
    public static String changeIpToAddress(String ip) {
        //获取searcher
        Searcher searcher = null;
        try {
            searcher = getSearcher();
            return searcher.search(ip);
        } catch (Exception e) {
            log.error(String.format("ip转地址报错:%s", e.getMessage()));
            e.printStackTrace();
            return "";
        } finally {
            try {
                if (Objects.nonNull(searcher)) {
                    searcher.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
}
